#include "Bezier.h"


Bezier::Bezier() :
	m_limInferior(0.0f), m_limSuperior(1.0f)
{
}


void Bezier::init(std::vector<glm::vec3> vecPtsControl) {
	if ( vecPtsControl.size() == 0 ){
		throw std::invalid_argument("Se necesitan mas puntos de control");
	}

	// El grado del poliminio es uno menor que la cantidad de puntos
	this->m_bernsPoli.init( vecPtsControl.size() -1 );
	this->m_ptsControl.assign( vecPtsControl.begin(), vecPtsControl.end() );
}


glm::vec3 Bezier::eval(float u) const {
	// Chequea que este definido en el intervalo correcto
	if (u < this->m_limInferior || u > this->m_limSuperior){
		return glm::vec3(0.0f, 0.0f, 0.0f);
	}

	const unsigned int cantPuntos = this->m_ptsControl.size();

	// P(u) = SUM Pk * C(n, k) * u^k * (1-u)^(n-k)
	glm::dvec3 vDoble(0.0, 0.0, 0.0);
	for (unsigned int i = 0; i< cantPuntos; ++i){
		vDoble += glm::dvec3( this->m_ptsControl[i] ) * this->m_bernsPoli.eval(u, i);
	}

	return glm::vec3( vDoble );
}


float Bezier::getLimiteSuperior() const {
	return this->m_limSuperior;
}


float Bezier::getLimiteInferior() const {
	return this->m_limInferior;
}

